package com.share.finance.risk.rules.service.impl.exe;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.share.common.utils.FileUtil;
import com.share.finance.risk.rules.mapper.StrategyConfMapper;
import com.share.finance.risk.rules.model.db.StrategyConf;
import com.share.finance.risk.rules.model.translate.ifs.IfStruct;
import com.share.finance.risk.rules.service.exe.TranslateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class TranslateServiceImpl implements TranslateService {

    @Resource
    private StrategyConfMapper strategyConfMapper;

    //翻译一个策略
    @Override
    public String translateStrategy(JSONObject req) {
        String result = null;
        Set<String> sets = req.keySet();
        for (String flag : sets) {
            switch (flag) {
                case "then":
                    result = keyThen(req.getJSONArray(flag));
            }
        }

        return result;
    }

    /**
     * 翻译多个节点
     *
     * @param strategyIds
     * @return
     */
    @Override
    public String translateFlow(List<Long> strategyIds) {
        String reStr = "";
        List<StrategyConf> list = strategyConfMapper.selectBatchIds(strategyIds);
        if (CollectionUtils.isEmpty(list)) {
            throw new RuntimeException("规则不存在");
        } else {
            for (StrategyConf item : list) {
                String json = item.getJson();
                if (StringUtils.isNotBlank(json)) {
                    reStr += translateStrategy(JSON.parseObject(json));
                }
            }
        }
        return reStr;
    }

    //对then的处理
    private String keyThen(JSONArray jsonArray) {
        StringBuffer sb = new StringBuffer();
        for (Object obj : jsonArray) {
            JSONObject jsonObj = (JSONObject) obj;
            String type = jsonObj.getString("type");
            if ("if,else if,".contains(type + ',')) {//必须是标准格式
                String tmp = keyThenIfOrElseIf(jsonObj);
                sb.append(tmp);
            } else if ("else,".contains(type + ',')) {
                String tmp = keyThenElse(jsonObj);
                sb.append(tmp);
            }
        }
        return sb.toString();
    }

    private String keyThenIfOrElseIf(JSONObject jsonObj) {
        StringBuffer sb = new StringBuffer();

        //if 或者elseif 条件
        String type = jsonObj.getString("type");
        sb.append(type + " (");

        //只有一个层
        JSONArray constraints = jsonObj.getJSONArray("constraint");
        int size = constraints.size();
        for (int i = 0; i < size; i++) {
            JSONObject constraint = constraints.getJSONObject(i);
            String res = keyThenConstraint(constraint);
            sb.append(res);
        }
        sb.append(")");

        //then部分
        sb.append("{" + System.lineSeparator());
        JSONArray results = jsonObj.getJSONArray("result");
        for (Object obj : results) {
            JSONObject result = (JSONObject) obj;
            String res = keyThenResult(result);
            sb.append(String.format("%s", res));
        }
        String reasonCode = jsonObj.getString("reasonCode");
        if (StringUtils.isNotBlank(reasonCode)) {
            sb.append(String.format("output['reasonCode']='%s';" + System.lineSeparator(), reasonCode));
        }

        sb.append(System.lineSeparator() + "}");

        return sb.toString();
    }

    private String keyThenElse(JSONObject jsonObj) {
        StringBuffer sb = new StringBuffer();

        //else 部分
        String type = jsonObj.getString("type");
        sb.append(type + " {" + System.lineSeparator());
        JSONArray results = jsonObj.getJSONArray("result");
        for (Object obj : results) {
            JSONObject result = (JSONObject) obj;
            String res = keyThenResult(result);
            sb.append(String.format("%s", res));
        }
        String reasonCode = jsonObj.getString("reasonCode");
        if (StringUtils.isNotBlank(reasonCode)) {
            sb.append(String.format("output['reasonCode']='%s';" + System.lineSeparator(), reasonCode));
        }

        sb.append(System.lineSeparator() + "}");

        return sb.toString();
    }

    /**
     * 一行赋值表达式
     *
     * @param jsonObj
     * @return
     */
    private String keyThenResult(JSONObject jsonObj) {
        String operator = jsonObj.getString("operator");
        JSONObject left = jsonObj.getJSONObject("left");
        String s1 = keyThenParamItem(left);
        JSONObject right = jsonObj.getJSONObject("right");
        String s2 = keyThenParamItem(right);
        String result = s1 + operator + s2 + ";" + System.lineSeparator();
        return result;
    }

    /**
     * 一行条件表达式
     *
     * @param jsonObj
     * @return
     */
    private String keyThenConstraint(JSONObject jsonObj) {
        String operator = jsonObj.getString("operator");

        JSONObject left = jsonObj.getJSONObject("left");
        String s1 = keyThenParamItem(left);

        JSONObject right = jsonObj.getJSONObject("right");
        String s2 = keyThenParamItem(right);
        String result = s1 + operator + s2;

        JSONArray fields = jsonObj.getJSONArray("fields");//内嵌的
        if (!CollectionUtils.isEmpty(fields)) {
            int size = fields.size();
            for (int i = 0; i < size; i++) {
                JSONObject field = (JSONObject) fields.get(i);
                String type = field.getString("type");
                String tmp = keyThenConstraint(field);
                result += System.lineSeparator() + type + "(" + tmp + ")";
            }
        }

        return result;
    }

    /**
     * 返回一个参数的格式
     *
     * @param jsonObj
     * @return
     */
    private String keyThenParamItem(JSONObject jsonObj) {
        StringBuffer sb = new StringBuffer();
        String type = jsonObj.getString("type");
        if ("var".equals(type)) {
            String name = jsonObj.getString("name");
            String paramType = jsonObj.getString("paramType");
            if ("INPUT".equals(paramType)) {
                sb.append(String.format("input['%s']", name));
            } else if ("OUTPUT".equals(paramType)) {
                sb.append(String.format("output['%s']", name));
            }
        } else if ("const".equals(type)) {
            String value = jsonObj.getString("value");
            sb.append(String.format("'%s'", value));//需要加上单引号
        } else if ("fn".equals(type)) {
            String method = jsonObj.getString("name");
            JSONArray parameters = jsonObj.getJSONArray("parameters");
            if (CollectionUtils.isEmpty(parameters)) {
                sb.append(String.format("%s()", method));
            } else {
                String tmpMethodParam = "";
                int size = parameters.size();
                for (int i = 0; i < size; i++) {
                    JSONObject param = (JSONObject) parameters.get(i);
                    String s = keyThenParamItem(param);
                    tmpMethodParam += "," + s;
                }
                sb.append(String.format("%s(%s)", method, tmpMethodParam.substring(1)));
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) throws Exception {
        String s = FileUtil.read("./doc/finance/if.json");
        JSONObject jsonObject = JSON.parseObject(s);
        IfStruct jsonObject1 = JSON.parseObject(s, IfStruct.class);
        String s1 = new TranslateServiceImpl().translateStrategy(jsonObject);
        System.out.println(s1);
    }
}
